Repository navigation
Fix the gamma hook landing on a garbage vtable slot - #433
Merged
Merged
Conversation
The check on the gamma index compared a std::optional with 0. An empty optional compares as less than any number, so "display_gamma_index != 0" was true exactly when the index had not been found. Dereferencing it wrote gamma_increase_fn at whatever slot that produced, and the render target's vtable pointer was then swapped to that copy. In the log it shows up as a failed search followed by "Hooked FRenderTarget!" on the next line, and the second eye keeps the gamma the hook was supposed to fix. Use has_value, and give up if the index is past the end of the copied vtable instead of writing outside it. Also log which of the two sources the gamma came from, once. A viewport that reports 2.2 and a missing viewport falling back to the constant 2.2 look the same on screen, so there was no way to tell a working hook from one that happens to look right. Only the first of them follows the game's own gamma setting. On its own this turns a silent vtable corruption into a warning. For the index to be found at all the searches in UESDK need fixing too, which is a separate change over there. With both, the hook installs on The Outer Worlds 2, Silent Hill 2 and Gylt, at gamma index 7, 5 and 4, and the second eye matches the first.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The check on the gamma index compares a
std::optionalwith 0:An empty optional compares as less than any number, so this is true exactly when the
index was not found.
gamma_increase_fnthen gets written at whatever slot theempty optional produces, and the render target's vtable pointer is swapped to that
copy. In the log it looks like this:
Uses
has_value()now, and gives up if the index is past the end of the copied vtableinstead of writing outside it.
Also logs which of the two sources the gamma came from, once. A viewport reporting 2.2
and a missing viewport falling back to the constant 2.2 give the same picture, so there
was no way to tell a working hook from one that happens to look right.
On its own this turns a silent vtable corruption into a warning. For the index to be
found at all, the searches in UESDK need fixing too, which is a separate PR over there:
https://github.com/praydog/UESDK/pull/2. The two don't depend on each other to build or
merge, they just need each other to fix the dark eye.
Tested
Release build, three games with the native stereo fix on. With both changes the hook
installs and the second eye matches the first. Gamma values are from the new log line:
Each value matches that game's own gamma setting. I changed The Outer Worlds 2 from 2.2
to 2.0 and the logged value followed, so it is reading the viewport and not the 2.2
fallback.